package com.framework.common;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.shiro.SecurityUtils;

import com.framework.shiro.realm.ShiroDbRealm.ShiroUser;
import com.framework.util.Clock;

@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class FieldsPlugin implements Interceptor {

	@Override
	@SuppressWarnings("rawtypes")
	public Object intercept(Invocation invocation) throws Throwable {
		Object param = invocation.getArgs()[1];
		if (param != null) {
			// 批量操作
			if (param instanceof Map) {
				Map map = (Map) param;
				if (map.containsKey("list")) {
					List list = (List) map.get("list");
					for (Object o : list) {
						process(o);
					}
				}
			} else {
				process(param);
			}

		}
		return invocation.proceed();
	}

	private void process(Object param) throws Throwable {
		// 单个操作
		if (param instanceof BaseEntity) {
			BaseEntity entity = (BaseEntity) param;
			ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			// 数据库更新
			Serializable id = BeanUtils.getProperty(entity, "id");
			if (id != null) {
				entity.setModifyUserId(user.getId());
				entity.setModifyUserName(user.getRealName());
				entity.setModifyTime(Clock.DEFAULT.getCurrentDate());
			}
			// 数据插入
			else {
				entity.setCreateUserId(user.getId());
				entity.setCreateUserName(user.getRealName());
				if (entity.getCreateTime() == null) {
					entity.setCreateTime(Clock.DEFAULT.getCurrentDate());
				}
				if (entity.getSort() != null) {
					entity.setSort(1);
				}
				if (entity.getEnabled() == null) {
					entity.setEnabled(Boolean.TRUE);
				}
				if (entity.getDeleteMark() == null) {
					entity.setDeleteMark(Boolean.FALSE);
				}
			}
			// 针对没有基础父类的实体类
		} else if (!(param instanceof String) && !(param instanceof Number) && !(param instanceof Map)) {
			try {
				Method getter = param.getClass().getDeclaredMethod("getId");
				if (getter != null) {
					Integer id = (Integer) getter.invoke(param);
					// 新增纪录
					if (id == null) {
						// 初始化有效
						Method enabled = param.getClass().getDeclaredMethod("setEnabled", Boolean.class);
						if (enabled != null) {
							enabled.invoke(param, Boolean.TRUE);
						}
						// 初始化删除标记
						Method deleteMark = param.getClass().getDeclaredMethod("setDeleteMark", Boolean.class);
						if (deleteMark != null) {
							deleteMark.invoke(param, Boolean.FALSE);
						}
						// 初始化排序
						Method sort = param.getClass().getDeclaredMethod("setSort", Integer.class);
						if (sort != null) {
							sort.invoke(param, 1);
						}
					}
				}
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties arg0) {

	}

}